package finbudget.client.lists;

import java.util.ArrayList;

import com.gwtplatform.dispatch.shared.ActionException;

import finbudget.client.lists.GetListOfItems.ListType;
import finbudget.client.lists.GetListOfItems.Type;

public class CompositeListType extends ListType implements ListTypeElement, CriterialList {
	private static final long serialVersionUID = -4177339287520303846L;

	/**
	 * Name is used to identify list on the client.
	 */
	private String name;
	private ArrayList<ListType> lists;

	/** Serialization requirement */
	protected CompositeListType() {
		super();
		type = Type.COMPOSITE;
	}

	public CompositeListType(String name, String base) {
		super();
		type = Type.COMPOSITE;
		this.name = name;
		this.base = base;	// base must be set to be used as a reference on the client
	}

	public CompositeListType addList(ListType list) {
		if (list != null) {
			if (lists == null) {
				lists = new ArrayList<ListType>(2);
			}
			lists.add(list);
		}
		return this;
	}

	public ArrayList<ListType> getLists() {
		return lists;
	}

	public String getName() {
		return name;
	}

	@Override
	public ListType clone() {
		CompositeListType newList = new CompositeListType(name, base);
		if (lists != null) {
			for (ListType item : lists) {
				newList.addList(item.clone());
			}
		}
		return newList;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj != null && this.getClass().equals(obj.getClass())) {
			CompositeListType c = (CompositeListType) obj;
			if (this.lists == null && c.lists == null) {
				return true;
			}
			if (this.lists != null && c.lists != null) {
				if (this.lists.size() == c.lists.size()) {
					if (c.lists.containsAll(this.lists)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	@Override
	public GetListOfItemsResult getList(ListTypeVisitor visitor, GetListOfItemsAction action) throws ActionException {
		return visitor.getList(this, action);
	}

	@Override
	public void setCriterion(String field, String value) {
		if (lists != null) {
			for (ListType list : lists) {
				if (list instanceof CriterialList) {
					((CriterialList) list).setCriterion(field, value);
				}
			}
		}
	}

}
